package com.asteros.client;

import java.util.ArrayList;
import java.util.Collections;

import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.CanvasGradient;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.canvas.dom.client.CssColor;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
//import com.google.gwt.event.dom.client.MouseMoveEvent;
//import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Asteros implements EntryPoint {
	static ArrayList<Celda> celdas = new ArrayList<Celda>();
	//static ArrayList<Ficha> fichas = new ArrayList<Ficha>();
	final static double canvasx =800;
	final static double canvasy = 700;
	final static double x =canvasx/2;
	final static double y = canvasy/2;
	
	static Timer t;
	
	boolean miTurno = false;
	char miColor = 'b';
	boolean moviendo = false; //o tan solo moviendo
	ArrayList<Integer> miTirada = new ArrayList<Integer>();//las celdas en las que hizo click
	Celda seleccionada; //celda seleccionada para mover
	
	static Context2d ctx;
	CanvasGradient grd;
	static Image hexagris = new Image("img/asteros-hexagono-gris32.png");
	static Image hexaazul = new Image("img/asteros-hexagono-azul32.png");
	static Image hexarojo = new Image("img/asteros-hexagono-rojo32.png");
	static ImageElement hexagrise = ImageElement.as((hexagris).getElement());
	static ImageElement hexaazule = ImageElement.as((hexaazul).getElement());
	static ImageElement hexarojoe = ImageElement.as((hexarojo).getElement());
	
	static Image piezab = new Image("img/asteros-pieza-blanca32.png");
	static Image piezan = new Image("img/asteros-pieza-negra32.png");
	static ImageElement piezabe = ImageElement.as((piezab).getElement());
	static ImageElement piezane = ImageElement.as((piezan).getElement());
	
	int mouseX;
	int mouseY;
	Canvas canvas;
	
	int columnas = 10;//las columnas de celdas que se graficaran
	
	public void onModuleLoad() {
		//CANVAS
	    canvas = Canvas.createIfSupported();
	    canvas.getCanvasElement().setId("canvas");
	    canvas.setCoordinateSpaceHeight(700);
	    canvas.getCanvasElement().setWidth(800);
		
	    RootPanel.get().add(canvas);
	    
	    ctx = canvas.getContext2d();
	    
	    // Create gradient
	    grd=ctx.createRadialGradient(x,y,100,x,y,500);
	    grd.addColorStop(0,"white");
	    grd.addColorStop(1,"blue");
	    ctx.setFont("15px Arial");
	    
		//Celda.tablero(x, y, 3);
		new Celda('g', x, y, 0).crearVecinos(columnas);
		//Window.alert("Graficar");
		
		Collections.sort(celdas);
		
		//graficarTablero(1);//TODO calibrar timing correcto
		orillas();
		graficarTablero(); //TODO por aquello del error misterioso
		//TODO determinar color por callback servidor
		miColor = 'n';
		miTurno = true; 
		
		//////////Comienza el juego/////////////////
		canvas.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				if(miTurno){
					mouseX = event.getRelativeX(canvas.getElement());
					mouseY = event.getRelativeY(canvas.getElement());
					if(tiroValido(mouseX, mouseY)){
						tiro(mouseX, mouseY);
					}
				}
			}
		});
		/** canvas.addMouseMoveHandler(new MouseMoveHandler() {
		      public void onMouseMove(MouseMoveEvent event) {
		        mouseX = event.getRelativeX(canvas.getElement());
		        mouseY = event.getRelativeY(canvas.getElement());
		      }
		    });
		*/
		
	}
		
	private boolean tiroValido(int xx, int yy){
		Celda tiro = Celda.getCelda(xx, yy);
		if(tiro == null){
			return false;
		}
		
		if(moviendo){ //ya se ha seleccionado una ficha para moverla
			if(seleccionada.equals(tiro)){
				return true;
			}
			if(tiro.ficha != null){
				return false;
			}
			
			//movimiento sin comer 
			if(seleccionada.esVecino(tiro) != -1){ //si son vecinos...
				return true;
			}
			
			//movimiento comiendo
			Celda vecinos[] =tiro.getVecinos();
			for(int i= 0; i<6; i++){
				if(vecinos[i] != null)
				if(vecinos[i].ficha != null)
				if(vecinos[i].ficha.color != miColor){
					if(vecinos[i].getVecinos()[i].equals(tiro)){
						return true;
					}
				}
			}
			return false; 
		}else{
			if(tiro.ficha!=null){//se seleciona una ficha para moverla
				return tiro.ficha.color == miColor;
			}else{//ficha nueva
				return true;
			}
		}
	}
	
	private void tiro(int xx, int yy){
		miTirada.add(celdas.indexOf(Celda.getCelda(mouseX, mouseY)));
		Celda tiro = Celda.getCelda(xx, yy);
		
		if(moviendo){
			if(seleccionada.equals(tiro)){
				cederTurno();
				return;
			}
			new Ficha(tiro, seleccionada.ficha.color);
			if(seleccionada.esVecino(tiro) == -1){ //no es un vecino sino que salto
				Celda vecinos[] =tiro.getVecinos();
				for(int i= 0; i<6; i++){
					if(vecinos[i] != null)
					if(vecinos[i].ficha != null)
					if(vecinos[i].ficha.color != miColor){
						if(vecinos[i].getVecinos()[i].equals(tiro)){
							vecinos[i].ficha = null;
						}
					}
				}
				seleccionada.ficha = null;
				seleccionada = tiro;
				graficarTablero();
			}else{
				seleccionada.ficha = null;
				cederTurno();
			}
			
		}else{
			if(tiro.ficha!=null){//se seleciona una ficha para moverla
				moviendo = true;
				//brillar seleccionada TODO
				seleccionada = tiro;
				ctx.fillText("o", tiro.centrox-5, tiro.centroy+5);
				
				//brillar END (la ultima, creo)
			}else{//ficha nueva
				new Ficha(tiro, 'n');
				cederTurno();
			}
		}
	}
	 private void cederTurno(){
		 graficarTablero();
		 miTurno = false;
		 seleccionada = null;
		 moviendo = false;
		//TODO callback servidor
		/**servidor.alServidor(miTirada, new AsyncCallback<int>() {
		 @Override
			public void onFailure(Throwable caught) {
				Window.alert("error al recibir respuesta");	
			}
			@Override
			public void onSuccess(int result) {
				new Ficha(result, 'b');
				graficarTablero();
				teToca = true;
			}
		});
		 */
		 //mientras tanto
		 t = new Timer() {
			@Override
			public void run() {
				new Ficha(celdas.get(AI()), 'b');
				graficarTablero();
				miTurno = true;
			}
		};
		t.schedule(380);
		miTirada = new ArrayList<Integer>();
	 }

	private int AI(){
		int res;
		do{
			res = (int) (Math.random() * celdas.size());
		}while(!tiroValido((int)celdas.get(res).centrox, (int)celdas.get(res).centroy));
		return res;
	}
	
	/** TODO
	static int index = 0;
	private static void graficarTablero(int miliseg){
		t = new Timer() {
			@Override
			public void run() {
				graficar(celdas.get(index++));
				if(index >= celdas.size()){
					t.cancel();
				}
			}
		};
		t.scheduleRepeating(miliseg);
	}*/
	
	private void graficarTablero() {
		ctx.setFillStyle(grd);
		ctx.fillRect(0, 0, 800, 700);
		evaluar();
		for(Celda cel : celdas){
				graficar(cel);
			}
		//turno
		ctx.setFillStyle(CssColor.make("rgba(0, 0, 0, 1)"));
		ctx.fillText("Turno:", 650, 40);
		if(miTurno ^ miColor == 'b'){
			ctx.drawImage(piezane, 700, 40, 30, 30);//si son diferentes en el if
		}else{
			ctx.drawImage(piezabe, 700, 40, 30, 30);
		}
	}
	

	private void evaluar(){
		for(Celda cel : celdas){
			cel.color = 'g';
		}
		for(Celda cel : celdas){ //todas las celdas
			if(cel.ficha != null){		
				for(Celda vecino : cel.vecinos){ //vecinos
					if(vecino.ficha != null){//
						vecino.color = 'g';
					}else{						
						boolean territorioCompartido = false;
						for(Celda vecinoDeVecino : vecino.vecinos){ //vecinos de vecino
							if(vecinoDeVecino.ficha !=null){
								if(vecinoDeVecino.ficha.color != cel.ficha.color){//si es del otro color...
									territorioCompartido = true;
									break;
								}
							}
						}
						if(!territorioCompartido){
							vecino.color = (cel.ficha.color == 'n')? 'r':'a'; //TODO rojo para negro. azul para blanco
						}
					}
				}
			}
		}
	}

	public static void graficar(Celda cel){
		if(cel.color == 'g'){
			ctx.drawImage(hexagrise, cel.posx, cel.posy, 30, 30);
		}
		if(cel.color == 'r'){
			ctx.drawImage(hexarojoe, cel.posx, cel.posy, 30, 30);
		}
		if(cel.color == 'a'){
			ctx.drawImage(hexaazule, cel.posx, cel.posy, 30, 30);
		}
		//su ficha
		if(cel.ficha != null){
			graficar(cel.ficha);
		}
		/**borrar TODO
		int vecin = 0;
		for(Celda c: cel.vecinos){
			if(c != null) vecin++;
		}
		ctx.fillText(""+vecin, cel.centrox-5, cel.centroy+5);*/
	}
	
	public static void graficar(Ficha fich){
		Celda cel = fich.celda;
		if(fich.color == 'b'){
			ctx.drawImage(piezabe, cel.posx, cel.posy, 30, 30);
		}
		if(fich.color == 'n'){
			ctx.drawImage(piezane, cel.posx, cel.posy, 30, 30);
		}
	}
	
	//solo se usa una vez
	private void orillas(){
		for(Celda ce: celdas){
			double x = ce.centrox;
			double y = ce.centroy;
			double angulo;
			double separacion = 30;
				
			if(ce.columna >= columnas){ 
				int conteo = 0;
				Celda orillas[] = new Celda[6];
					for(int i=0; i<6; i++){
						angulo = i * 60;
						x = ce.centrox + separacion * Math.sin(Math.toRadians(angulo));
						y = ce.centroy + separacion * Math.cos(Math.toRadians(angulo));
						
						Celda celd = Celda.getCelda(x, y);
						if(Asteros.celdas.contains(celd)){
							conteo++;
						}
						orillas[i] = celd;
					}
					ce.vecinos = new Celda[conteo];
					conteo = 0;
					for(Celda c : orillas){
						if(c != null){
							ce.vecinos[conteo++] = c; 
						}
					}
		}}
	}
}










